home *** CD-ROM | disk | FTP | other *** search
/ 10,000 Great Games / 10,000 Great Games.iso / Product / 66 / data1.cab / Source_Files / Src / Joy.cpp < prev    next >
C/C++ Source or Header  |  2000-01-16  |  6KB  |  283 lines

  1. #include "stdafx.h"
  2.  
  3. char joy_str[kMaxJoys][MAX_PATH];
  4. GUID *joy_guid[kMaxJoys];
  5. DWORD joy_fire[kMaxJoys], joy_jetpack[kMaxJoys], joy_mine[kMaxJoys];
  6.  
  7. static BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
  8. {
  9.     // Check if string matches the stored description of the controller
  10.     // and if so store GUID
  11.  
  12.     for (int i = 0; i < kMaxJoys; i++)
  13.         if (eq(lpddi->tszInstanceName, joy_str[i]))
  14.             joy_guid[i] = new GUID(lpddi->guidInstance);
  15.  
  16.     return DIENUM_CONTINUE;   
  17. }
  18.  
  19. static BOOL CALLBACK DIEnumDevicesProc2(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
  20. {
  21.     // Check if none is selected and an unused joystick is found
  22.  
  23.     for (int i = 0; i < kMaxJoys; i++)
  24.         if (joy_guid[i] == 0)
  25.         {
  26.             // check if the joystick is not already used
  27.             for (int j = 0; j < kMaxJoys && !eq(lpddi->tszInstanceName, joy_str[j]); j++)
  28.                 continue;
  29.  
  30.             // assign it
  31.             if (j >= kMaxJoys)
  32.             {
  33.                 strcpy(joy_str[i], lpddi->tszInstanceName);
  34.  
  35.                 joy_guid[i] = new GUID(lpddi->guidInstance);
  36.  
  37.                 joy_fire[i] = DIJOFS_BUTTON0;
  38.                 joy_jetpack[i] = DIJOFS_BUTTON1;
  39.                 joy_mine[i] = DIJOFS_BUTTON2;
  40.             }
  41.         }
  42.     
  43.     return DIENUM_CONTINUE;   
  44. }
  45.  
  46. void init_joystick()
  47. {
  48.     // Reset the GUIDs
  49.     for (int i = 0; i < kMaxJoys; i++)
  50.         joy_guid[i] = NULL;
  51.  
  52.     // Search GUID for selected controllers
  53.  
  54.     DI->EnumDevices(DIDEVTYPE_JOYSTICK, DIEnumDevicesProc, 0, DIEDFL_ATTACHEDONLY);
  55.  
  56.     // Make sure something is selected
  57.  
  58.     DI->EnumDevices(DIDEVTYPE_JOYSTICK, DIEnumDevicesProc2, 0, DIEDFL_ATTACHEDONLY);
  59. }
  60.  
  61. void deinit_joystick()
  62. {
  63.     // Delete GUIDs
  64.  
  65.     for (int i = 0; i < kMaxJoys; i++)
  66.         safe_delete(&joy_guid[i]);
  67. }
  68.  
  69. LPDIRECTINPUTDEVICE2 create_input_device_joystick(GUID *guid)
  70. {
  71.     LPDIRECTINPUTDEVICE2 joystick;
  72.  
  73.     // Create DirectInput device
  74.  
  75.     joystick = create_input_device(*guid);
  76.  
  77.     if (FAILED(joystick->SetCooperativeLevel(mainwindowhandle, DISCL_EXCLUSIVE | DISCL_FOREGROUND)))
  78.         error("Unable to set cooperative level for joystick");
  79.  
  80.     if (FAILED(joystick->SetDataFormat(&c_dfDIJoystick)))
  81.         error("Unable to set data format to joystick");
  82.  
  83.     // Set range
  84.  
  85.     DIPROPRANGE diprg; 
  86.  
  87.     diprg.diph.dwSize = sizeof(diprg); 
  88.     diprg.diph.dwHeaderSize = sizeof(diprg.diph); 
  89.     diprg.diph.dwObj = 0; 
  90.     diprg.diph.dwHow = DIPH_DEVICE; 
  91.     diprg.lMin = JOY_MIN; 
  92.     diprg.lMax = JOY_MAX; 
  93.  
  94.     if (FAILED(joystick->SetProperty(DIPROP_RANGE, &diprg.diph)))
  95.         error("Unable to set range for joystick");
  96.  
  97.     // Set deadzone
  98.     
  99.     DIPROPDWORD dipdw;
  100.  
  101.     dipdw.diph.dwSize = sizeof(dipdw); 
  102.     dipdw.diph.dwHeaderSize = sizeof(dipdw.diph); 
  103.     dipdw.diph.dwObj = 0;
  104.     dipdw.diph.dwHow = DIPH_DEVICE;
  105.     dipdw.dwData = JOY_DEAD;
  106.  
  107.     if (FAILED(joystick->SetProperty(DIPROP_DEADZONE, &dipdw.diph)))
  108.         error("Unable to set dead zone for joystick");
  109.  
  110.     return joystick;
  111. }
  112.  
  113. cJoystick::cJoystick(int num)
  114. {
  115.     // Create joystick device
  116.     
  117.     if (joy_guid[num] == 0)
  118.         joystick = 0;
  119.     else
  120.         joystick = create_input_device_joystick(joy_guid[num]);
  121.  
  122.     // Create button offsets
  123.  
  124.     fire = joy_fire[num] == 0xffffffff? 0 : (BYTE *)&state + joy_fire[num];
  125.     jetpack = joy_jetpack[num] == 0xffffffff? 0 : (BYTE *)&state + joy_jetpack[num];
  126.     mine = joy_mine[num] == 0xffffffff? 0 : (BYTE *)&state + joy_mine[num];
  127. }
  128.  
  129. cJoystick::~cJoystick()
  130. {
  131.     if (joystick != 0)
  132.     {
  133.         joystick->Unacquire();
  134.  
  135.         joystick->Release();
  136.     }
  137. }
  138.  
  139. void cJoystick::reset()
  140. {
  141. }
  142.  
  143. void cJoystick::determine(cPlayer *p)
  144. {
  145.     // Check if this joystick is present
  146.  
  147.     if (joystick == 0)
  148.         return;
  149.  
  150.     // Poll this joystick
  151.  
  152.     if (FAILED(joystick->Poll()))
  153.     {
  154.         // Joystick input was lost, reacquire
  155.  
  156.         joystick->Acquire();
  157.  
  158.         if (FAILED(joystick->Poll()))
  159.             return;
  160.     }
  161.  
  162.     // Get the state of the joystick
  163.  
  164.     if (FAILED(joystick->GetDeviceState(sizeof(state), &state)))
  165.     {
  166.         // Joystick input was lost, reacquire
  167.         
  168.         joystick->Acquire();
  169.  
  170.         if (FAILED(joystick->GetDeviceState(sizeof(state), &state)))
  171.             return;        
  172.     }
  173.  
  174.     // Make discrete states
  175.  
  176.     int left = state.lX < 0,
  177.         right = state.lX > 0,
  178.         up = state.lY < 0,
  179.         down = state.lY > 0,
  180.         f = fire == 0? FALSE : *fire & 0x80;
  181.  
  182.     // Cannot do anything when not active
  183.  
  184.     if (!p->is_active())
  185.            return;
  186.        
  187.     // Check fire button
  188.     
  189.     if (mine == 0? FALSE : *mine & 0x80)
  190.     {
  191.         p->fire_down();
  192.     }
  193.     else if (f)
  194.     {
  195.         if (up)
  196.             p->fire_up();
  197.         else if (down && (left || right))
  198.             p->fire_down();
  199.         else
  200.             p->fire();
  201.     }
  202.     
  203.     // Cannot do anything more when captured
  204.     
  205.     if (p->is_captured())
  206.         return;
  207.             
  208.     // Jetpack
  209.     
  210.     if (jetpack == 0? FALSE : *jetpack & 0x80)
  211.         p->jet_on();
  212.     else
  213.         p->jet_off();
  214.         
  215.     // Do movement
  216.         
  217.     if (p->is_walking())
  218.     { 
  219.         if (left)
  220.             p->walk_left();
  221.         else if (right)
  222.             p->walk_right();
  223.         else
  224.             p->walk_h_halt();
  225.         
  226.         if (up && !f)
  227.             p->jump();
  228.         else if (down)
  229.             p->duck();
  230.     }
  231.     else if (p->is_ducked())
  232.     {
  233.         if (!down)
  234.             p->stand();
  235.         
  236.         if (left)
  237.             p->duck_left();
  238.         else if (right)
  239.             p->duck_right();
  240.     }
  241.     else if (p->is_jumping())
  242.     {
  243.         if (left)
  244.             p->jump_left();
  245.         else if (right)
  246.             p->jump_right();
  247.         else
  248.             p->jump_h_halt();
  249.     }
  250.     else if (p->is_jetting())
  251.     {
  252.         if (up)
  253.             p->jet_up();
  254.         else if (down)
  255.             p->jet_down();
  256.         else
  257.             p->jet_v_halt();
  258.         
  259.         if (left)
  260.             p->jet_left();
  261.         else if (right)
  262.             p->jet_right();
  263.         else
  264.             p->jet_h_halt();
  265.     }
  266.     else if (p->is_climbing())
  267.     {
  268.         if (up)
  269.             p->climb_up();
  270.         else if (down)
  271.             p->climb_down();
  272.         else
  273.             p->climb_v_halt();
  274.         
  275.         if (left)
  276.             p->climb_left();
  277.         else if (right)
  278.             p->climb_right();
  279.         else
  280.             p->climb_h_halt();
  281.     }    
  282. }
  283.